﻿//******************************************************************************************
// File Name        : Qspi_functions.c
// Purpose          : This file consists of functions related to working of QSPI controller
//******************************************************************************************


//--------------------------------------------------------------------------------------
//To initialize the QSPI controller module
//--------------------------------------------------------------------------------------

void qspi_init(unsigned int CR_value,unsigned int DCR_value)

        {
          //QSPI IP configuration

            write_reg(CR,CR_value);

          //QSPI flash configuration
            write_reg(DCR,DCR_value);

          //Delay of 1ms is inserted to wait for Chip_EN of flash
            delay(25000);

        }


//--------------------------------------------------------------------------------------
//To perform MDID and DID read from flash
//--------------------------------------------------------------------------------------

void read_MDID_DID(unsigned int DLR_value,unsigned int CCR_value,unsigned int address)

        {
          //16 bytes of data
            write_reg(DLR,DLR_value);

          //
            write_reg(CCR,CCR_value); 

          //sector address
            write_reg(AR,address);

          //Function call to wait for TCF flag to set
            wait_for_tcf_flag(SR);

          //Read the 4 Bytes of data from flash
            delay(1000);
            read_reg(DR);

          //Clear flags in SR
            write_reg(FCR,0x0000001b);

        }


//--------------------------------------------------------------------------------------
//To Erase a sector or Block or Chip of flash
//--------------------------------------------------------------------------------------

/*void S_B_C_Erase(unsigned int CCR_value,unsigned int address)

        {
          //Function call to Set Write Enable Latch
            Flash_W_Enable();

          //
            write_reg(CCR,CCR_value);

          //Sector address
            write_reg(AR,address);

          //Function call to wait for TCF flag to set
            wait_for_tcf_flag(SR);

          //Clear flags in SR
            write_reg(FCR,0x1b);

          //Function call to wait for WIP signal of flash to transit to low
            wait_for_wip_flag(DR);

        }*/


//--------------------------------------------------------------------------------------
//To perform Page program to flash
//--------------------------------------------------------------------------------------

/*void PP_SPI(unsigned int DLR_value, unsigned int CCR_value, unsigned int address)

        {
          //
            Flash_W_Enable();//To Set Write Enable Latch

          //Clear flags in SR
            write_reg(FCR,0x1b);   //reset flags 

          //
            write_reg(DLR,DLR_value);// 16 bytes

          //
            write_reg(CCR,CCR_value);//update data here like instruction=12, INDWR,Single,

          //
            write_reg(AR,address);
            
            for(int i=0;i<=DLR_value;i++)
            {
            delay(1000);
            write_reg(DR,wr_data[i]);
            }


          //Function call to wait for TCF flag to set
            wait_for_tcf_flag(SR);

          //Clear flags in SR
            write_reg(FCR,0x1b);   //reset flags 

          //Function call to wait for WIP signal of flash to transit to low
            wait_for_wip_flag(DR);

          //To understand the write is complete
            printf("WrDone");

        } */


//--------------------------------------------------------------------------------------
//To perform flash write enable
//--------------------------------------------------------------------------------------

void Flash_W_Enable()
        {
          //FMODE=0, DMODE=0, ADSIZE=0, ADMODE=0, IMODE=11, INSTRUCTION=0x06
            write_reg(CCR,0x00000306);

          //Function call to wait for TCF flag to set
            wait_for_tcf_flag(SR);

          //Clear flags in SR
            write_reg(FCR,0x1b); 

        }

//--------------------------------------------------------------------------------------
//To perform QPI Mode enable
//--------------------------------------------------------------------------------------

void EN_QPI_mode(unsigned int CCR_value)
        {
          //FMODE=00, DMODE=00, ADSIZE=11, ADMODE=00, IMODE=01, INSTRUCTION=0x35
            write_reg(CCR,CCR_value);

          //Function call to wait for TCF flag to set
            wait_for_tcf_flag(SR);

          //Clear flags in SR
            write_reg(FCR,0x1b); 

        }

//--------------------------------------------------------------------------------------
//To perform read operation from flash
//--------------------------------------------------------------------------------------

/*void read_data(unsigned int DLR_value,unsigned int CCR_value,unsigned int address)

        {
          //16 bytes of data
            write_reg(DLR,DLR_value);

          //
            write_reg(CCR,CCR_value); 

          //sector address
            write_reg(AR,address);

          //Function call to wait for TCF flag to set
            wait_for_tcf_flag(SR);

          //Read the (DLR_value+1) Bytes of data from flash
            for(int i=0;i<=DLR_value;i++)
            {
            delay(1000);
            read_reg(DR);
            }

          //Clear flags in SR
            write_reg(FCR,0x0000001b);

        }
*/

//--------------------------------------------------------------------------------------
//To wait for WIP signal of flash to transit to low
//--------------------------------------------------------------------------------------

void wait_for_wip_flag(unsigned int rg_addr)

        {
          //Variable initialization
            unsigned int status,i=0;

          //Variable initialization
            unsigned long time_out=32;

          write_reg(PIR,0xF);

          // do-while loop starts here
                do{

                  //Clear flags in SR
                    write_reg(FCR,0x1b);

                  //2 bytes of data
                    write_reg(DLR,0x1);

                  //FMODE=1, DMODE=1, ADSIZE=11, ADMODE=01, IMODE=11, INSTRUCTION=0x05
                    write_reg(CCR,0x0B003F05); //09003505

                  //Address	
                    write_reg(AR,0x0);

                  //Function call to wait for TCF flag to set
                   // wait_for_tcf_flag(SR);

                    delay(1000);
                    unsigned int *rd_addr=(unsigned int *)rg_addr;
                    status = *(rd_addr);
                    printf("L%d",(status & 0x1));


                    i = i+1;

                    if (i == time_out)
                        {
                        printf("time_out");
                        break;
                        }


                }while(status & 0x1);


          //Clear flags in SR
            write_reg(FCR,0x1b);
        }
